package com.zmj.mobile.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmj.amc.sdk.entity.User;
import com.zmj.framework.base.service.impl.BaseServiceImpl;
import com.zmj.framework.exception.CustomException;
import com.zmj.framework.response.ResponseCode;
import com.zmj.framework.response.Result;
import com.zmj.framework.util.ThreadContextHandler;
import com.zmj.mobile.dto.AuditDTO;
import com.zmj.mobile.dto.QuoteItemDetailBaseDTO;
import com.zmj.mobile.dto.QuoteItemDetailDTO;
import com.zmj.mobile.dto.QuoteItemDetailInsertDTO;
import com.zmj.mobile.dto.QuoteItemDetailUpdateDTO;
import com.zmj.mobile.dto.QuoteItemMainBaseDTO;
import com.zmj.mobile.dto.QuoteItemMainIdDTO;
import com.zmj.mobile.dto.QuoteItemMainInsertDTO;
import com.zmj.mobile.dto.QuoteItemMainUpdateDTO;
import com.zmj.mobile.entity.OrgEntity;
import com.zmj.mobile.entity.QuoteItemDetailEntity;
import com.zmj.mobile.entity.QuoteItemMainEntity;
import com.zmj.mobile.enums.ExceptionEnum;
import com.zmj.mobile.mapper.IQuoteItemMainMapper;
import com.zmj.mobile.mapstruct.QuoteItemDetailMapStruct;
import com.zmj.mobile.mapstruct.QuoteItemMainMapStruct;
import com.zmj.mobile.process.AuditServiceEnum;
import com.zmj.mobile.process.AuditServiceFactory;
import com.zmj.mobile.process.IAuditService;
import com.zmj.mobile.service.IOrgService;
import com.zmj.mobile.service.IQuoteItemDetailService;
import com.zmj.mobile.service.IQuoteItemMainService;
import com.zmj.mobile.vo.QuoteItemMainIdVO;
import com.zmj.mobile.vo.QuoteItemMainVO;
import com.zmj.modules.flow.entity.dto.BpmTaskCcQueryDto;
import com.zmj.modules.flow.entity.vo.TodoTaskVO;
import com.zmj.modules.flow.service.FlowableService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;


/**
 * <p>
 * 采购询比价/定价主表 服务实现类
 * </p>
 *
 * @author lzy
 * @since 2024-02-01
 */
@Slf4j
@Service
public class QuoteItemMainServiceImpl extends BaseServiceImpl<IQuoteItemMainMapper, QuoteItemMainEntity> implements IQuoteItemMainService {

    @Autowired
    private IQuoteItemDetailService iQuoteItemDetailService;

    /**
     * @Description 导入采购询比价/定价明细
     * @Author ChengShenzhen
     * @Date 18:18 2024/2/1 0001
     **/
    @SneakyThrows
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void importExcel(MultipartFile file,int sheet) {

        //加载excel文件
        List<QuoteItemDetailDTO> quoteItemDetailDTOList = EasyExcel.read(file.getInputStream()).excelType(ExcelTypeEnum.XLSX)
                .head(QuoteItemDetailDTO.class)
                .sheet(sheet)
                .doReadSync();
        if (CollectionUtil.isEmpty(quoteItemDetailDTOList)) {
            throw new CustomException(ResponseCode.INTERNAL_SERVER_ERROR.getCode(), "导入数据为空,请检查!");
        }
        //详情表集合
        List<QuoteItemDetailEntity> quoteItemDetailEntityList = new ArrayList<>();
        //主表数据集合
        List<QuoteItemMainEntity> quoteItemMainEntities = new ArrayList<>();
        //申请编号集合
        List<String> applyNum = new ArrayList<>();
        //初始化采购询比价/定价数据
        for (QuoteItemDetailDTO quoteItemDetailDTO : quoteItemDetailDTOList) {
            QuoteItemDetailEntity quoteItemDetailEntity = new QuoteItemDetailEntity();
            //赋值详情数据到主表
            BeanUtil.copyProperties(quoteItemDetailDTO, quoteItemDetailEntity);
            //quoteItemDetailEntity.setQuoteItemId(System.currentTimeMillis());
            quoteItemDetailEntity.setQuoteItemId(Long.parseLong(quoteItemDetailDTO.getApplyNum()));
            quoteItemDetailEntityList.add(quoteItemDetailEntity);
            if (applyNum.contains(quoteItemDetailDTO.getApplyNum())) {
                continue;
            }
            applyNum.add(quoteItemDetailDTO.getApplyNum());
            //定制主表数据
            QuoteItemMainEntity quoteItemMainEntity = new QuoteItemMainEntity();
            BeanUtil.copyProperties(quoteItemDetailDTO, quoteItemMainEntity);
            quoteItemMainEntity.setId(Long.parseLong(quoteItemDetailDTO.getApplyNum()));
            quoteItemMainEntities.add(quoteItemMainEntity);

        }

        iQuoteItemDetailService.saveBatch(quoteItemDetailEntityList);
        this.saveBatch(quoteItemMainEntities);
    }

    @Resource
    private IQuoteItemMainMapper quoteItemMainMapper;
    @Resource
    private IQuoteItemDetailService quoteItemDetailService;
    @Resource
    private AuditServiceFactory auditServiceFactory;

    @Resource
    private IOrgService iOrgService;
    @Resource
    private FlowableService flowableService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public QuoteItemMainIdVO insert(QuoteItemMainInsertDTO insertDTO) {
        User user = new User();
        user.setUsername(insertDTO.getCreateUser());
        user.setRealName(insertDTO.getCreateUserName());
        ThreadContextHandler.setCurrentUser(user);

        Optional<OrgEntity> orgEntityOptional = iOrgService.getByUserName(insertDTO.getCreateUser());
        if (orgEntityOptional.isPresent()) {
            insertDTO.setDepartCode(orgEntityOptional.get().getOrgCode());
            insertDTO.setDepartName(orgEntityOptional.get().getOrgName());
        }

        QuoteItemMainEntity entity = QuoteItemMainMapStruct.INSTANCE.toQuoteItemMain(insertDTO);

        quoteItemMainMapper.insert(entity);
        Long quoteItemId = entity.getId();
        //保存明细
        saveDetailList(insertDTO, quoteItemId, true);

        IAuditService auditService = auditServiceFactory.getAuditService(AuditServiceEnum.getExample(AuditServiceEnum.QUOTE_ITEM_MAIN.getCode()));
        auditService.agree(AuditDTO.builder().id(quoteItemId).build());
        return QuoteItemMainIdVO.builder().id(quoteItemId).build();
    }

    @Override
    public QuoteItemMainVO getById(QuoteItemMainIdDTO idDTO) {
        Long id = idDTO.getId();
        QuoteItemMainEntity entity = checkExists(id);
        QuoteItemMainVO quoteItemMainVO = QuoteItemMainMapStruct.INSTANCE.toQuoteItemMainVO(entity);

        LambdaQueryWrapper<QuoteItemDetailEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(QuoteItemDetailEntity::getQuoteItemId, id);
        List<QuoteItemDetailEntity> list = quoteItemDetailService.list(queryWrapper);
        list = list == null ? new ArrayList<>() : list;
        quoteItemMainVO.setDetailList(list);

        //查询待办
        String flowId = entity.getFlowId();
        if (StringUtils.isEmpty(flowId)) {
            return quoteItemMainVO;
        }
        BpmTaskCcQueryDto bpmQueryDto = new BpmTaskCcQueryDto();
        bpmQueryDto.setProcInstId(flowId);
        bpmQueryDto.setSize(5);
        Result<Map<String, Object>> allTodoTasks = flowableService.getAllTodoTasks(bpmQueryDto);
        Map<String, Object> dataMap = allTodoTasks.getData();
        if (dataMap == null) {
            throw new CustomException(ExceptionEnum.GET_TASK_INFO_FAIL);
        }
        Page<Map<String, Object>> data = BeanUtil.fillBeanWithMap(dataMap, new Page<>(), false);
        List<Map<String, Object>> records = data.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            quoteItemMainVO.setTaskId("");
            return quoteItemMainVO;
        }
        //if (records.size() > 1) {
        //    //log.warn("业务id#{}#工作流id#{}#询价审批待办任务不唯一！", id, flowId);
        //}
        Map<String, Object> recordMap = records.get(0);
        TodoTaskVO todoTaskVO = BeanUtil.fillBeanWithMap(recordMap, new TodoTaskVO(), false);
        quoteItemMainVO.setTaskId(todoTaskVO.getTaskId());

        return quoteItemMainVO;
    }


    private void saveDetailList(QuoteItemMainBaseDTO baseDTO, Long quoteItemId, boolean insertFlag) {
        List<? extends QuoteItemDetailBaseDTO> detailList = insertFlag ? ((QuoteItemMainInsertDTO) baseDTO).getDetailList() : ((QuoteItemMainUpdateDTO) baseDTO).getDetailList();
        if (CollectionUtils.isNotEmpty(detailList)) {
            List<QuoteItemDetailEntity> targetList = new ArrayList<>();
            detailList.forEach(item -> {
                QuoteItemDetailEntity entity = insertFlag ? QuoteItemDetailMapStruct.INSTANCE.toQuoteItemDetail((QuoteItemDetailInsertDTO) item) : QuoteItemDetailMapStruct.INSTANCE.toQuoteItemDetail((QuoteItemDetailUpdateDTO) item);
                entity.setQuoteItemId(quoteItemId);
                targetList.add(entity);
            });
            if (insertFlag) {
                quoteItemDetailService.saveBatch(targetList);
            } else {
                quoteItemDetailService.saveOrUpdateBatch(targetList);
            }
        }
    }

    private QuoteItemMainEntity checkExists(Long id) {
        QuoteItemMainEntity entity = quoteItemMainMapper.selectById(id);
        if (entity == null) {
            throw new CustomException(ExceptionEnum.QUOTE_ITEM_MAIN_NOT_EXISTS);
        }
        return entity;
    }


}
